﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace WWWSiteHelper
{
    public partial class MainForm : Form
    {
        public static readonly string ConfigFile = "config.cfg";
        public static readonly int MaxRecentProjects = 5;
        private LinkedList<ProjectId> recentProjects = new LinkedList<ProjectId>();
        private Project currentProject;
        private AutoCompletition autoCompletition;
        public TabObservator tabObservator;

        public Project CurrentProject
        {
            get { return currentProject; }
            set
            {
                this.currentProject = value;
                UpdateProjectStatus();

                if (recentProjects.Contains(CurrentProject.Id))
                {
                    recentProjects.Remove(CurrentProject.Id);
                }
                recentProjects.AddFirst(CurrentProject.Id);
                if (recentProjects.Count > MaxRecentProjects)
                    recentProjects.RemoveLast();
                updateRecentProjects();
                // save
                Stream output = File.OpenWrite(ConfigFile);
                BinaryFormatter serializer = new BinaryFormatter();
                Console.WriteLine(recentProjects.Count);
                serializer.Serialize(output, recentProjects);
                output.Close();
            }
        }

        public MainForm()
        {
            InitializeComponent();
            autoCompletition = new AutoCompletition(dataGridView1);
            openLocalProjectDialog.Filter = "Projects (*"+ProjectId.ProjectFileExtension+")|*" + ProjectId.ProjectFileExtension + "|All files (*.*)|*.*";
            tabObservator = new TabObservator(this.tabControl1);
            tabObservator.TextChanged += tabObservator_TextChange;
            tabObservator.KeyUp += autoCompletition.AutoComplete;

            // avoid adding to recentProjects
            currentProject = new DefaultProjectId().LoadProject();

            // for easy testing
            AbstractFile f = new AbstractFile("TEST", AbstractFile.FileType.Html5, currentProject.Id);
            currentProject.AddFile(f);
            tabObservator.SetContext(f);

            UpdateProjectStatus();
            if (File.Exists(ConfigFile))
            {
                Stream input = File.OpenRead(ConfigFile);
                BinaryFormatter deserializer = new BinaryFormatter();
                recentProjects = (LinkedList<ProjectId>)deserializer.Deserialize(input);
                input.Close();
            }
            updateRecentProjects();
        }

        public void UpdateProjectStatus()
        {
            this.Text = "WWWSiteHelper - " + CurrentProject.Name;
            projectTreeView.Nodes.Clear();
            TreeNode root = new TreeNode(CurrentProject.Name);
            projectTreeView.Nodes.Add(root);
            foreach (AbstractFile file in CurrentProject.Files)
            {
                TreeNode node = new TreeNode(file.Name+"."+TypeConverter.getString(file.Type));
                node.Tag = file;
                root.Nodes.Add(node);
            }
            projectTreeView.ExpandAll();
        }

        private void updateRecentProjects()
        {
            if( recentProjects.Count > 0 )
                this.reopenToolStripMenuItem.Enabled = true;
            ToolStripItemCollection recentItems = this.reopenToolStripMenuItem.DropDownItems;
            recentItems.Clear();
            
            foreach (ProjectId project in recentProjects)
            {
                ToolStripItem item = new ToolStripMenuItem(
                    project.ToString(),
                    null,
                    new EventHandler(delegate(object o, EventArgs args) {
                        CurrentProject = ((ProjectId)((ToolStripMenuItem)o).Tag).LoadProject();
                    })
                );
                item.Tag = project;
                item.Size = new System.Drawing.Size(222, 22);
                recentItems.Add(item);
            }
        }

        private void tabObservator_TextChange(object sender, EventArgs e)
        {
            TextBox textBox = tabObservator.CurrentTextBox;
            if (textBox == null)
            {
                undoToolStripMenuItem.Enabled = redoToolStripMenuItem.Enabled = false;
                selectAllToolStripMenuItem.Enabled = false;
                saveToolStripMenuItem.Enabled = closeTabToolStripMenuItem.Enabled = false;
            }
            else
            {
                undoToolStripMenuItem.Enabled = textBox.CanUndo;
                selectAllToolStripMenuItem.Enabled = true;
                saveToolStripMenuItem.Enabled = closeTabToolStripMenuItem.Enabled = true;
            }

            // reset timer
            typingTimer.Stop();
            typingTimer.Start();
        }


        private void tabObservator_CursorChange(TextBox textBox)
        {
            if (textBox == null)
            {
                pasteToolStripMenuItem.Enabled = copyToolStripMenuItem.Enabled = cutToolStripMenuItem.Enabled = false;
            }
            else
            {
                copyToolStripMenuItem.Enabled = cutToolStripMenuItem.Enabled = (textBox.SelectedText.Length > 0);
                pasteToolStripMenuItem.Enabled = Clipboard.ContainsText();
            }
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabObservator.SaveCurrentContext();
        }

        private void localFileToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void newToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            new NewProjectDialog().ShowDialog(this);
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void typingTimer_Tick(object sender, EventArgs e)
        {
            if (tabObservator.CurrentTextBox!=null)
                webBrowser1.DocumentText = tabObservator.CurrentTextBox.Text;
            typingTimer.Stop();
        }

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {

        }

        private void localProjectToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            DialogResult result = openLocalProjectDialog.ShowDialog(this);
            if (DialogResult.OK.Equals(result))
            {
                ProjectId project = new LocalProjectId(openLocalProjectDialog.FileName);
                CurrentProject = project.LoadProject();
            }
            
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void newFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new NewFileDialog().ShowDialog(this);
        }

        private void saveAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabObservator.SaveEachContext();
        }

        private void projectTreeView_DoubleClick(object sender, EventArgs e)
        {
            AbstractFile f = (AbstractFile)projectTreeView.SelectedNode.Tag;
            if (f!=null)
                tabObservator.SetContext(f);
        }

        private void undoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabObservator.CurrentTextBox.Undo();
        }

        private void redoToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void cutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabObservator.CurrentTextBox.Cut();
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabObservator.CurrentTextBox.Copy();
        }

        private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabObservator.CurrentTextBox.Paste();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            projectTreeView.Visible ^= true;
            button1.Text = projectTreeView.Visible ? ">" : "<";
        }

        private void button1_MouseHover(object sender, EventArgs e)
        {
        }

        private void projectTreeView_MouseLeave(object sender, EventArgs e)
        {
        }

        private void generateTableToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new NewTableDialog(tabObservator.CurrentTextBox).ShowDialog(this);
        }

        private void openFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DefaultProjectId id = (DefaultProjectId)currentProject.Id;
            OpenFileDialog dialog = new OpenFileDialog();
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                string path = dialog.FileName;
                tabObservator.SetContext(id.OpenFile(path));
            }
        }

        private void closeTabToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabObservator.CloseTab();
        }

        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            tabObservator.CurrentTextBox.SelectAll();
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (tabObservator.AnyUnsaved)
            {
                switch (MessageBox.Show("Czy chcesz zapisać wszystkie pliki?", "Zamykanie", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning))
                {
                    case System.Windows.Forms.DialogResult.Yes:
                        tabObservator.SaveEachContext();
                        return;
                    case System.Windows.Forms.DialogResult.No:
                        return;
                    case System.Windows.Forms.DialogResult.Cancel:
                        e.Cancel = true;
                        return;
                }
            }
        }
    }
}
